package com.glory.gloryquickui.utils

import com.glory.gloryquickui.entity.BaseResponseBean
import rxhttp.wrapper.annotation.Parser
import rxhttp.wrapper.entity.ParameterizedTypeImpl
import rxhttp.wrapper.exception.ParseException
import rxhttp.wrapper.parse.AbstractParser
import rxhttp.wrapper.utils.convert
import java.io.IOException
import java.lang.reflect.Type

/**
 * 输入T,输出T,并对code统一判断
 *
 * 如果使用协程发送请求，wrappers属性可不设置，设置了也无效
 */
@Parser(name = "Response")
open class ResponseParser<T> : AbstractParser<T> {
    /**
     * 此构造方法适用于任意Class对象，但更多用于带泛型的Class对象，如：List<Student>
     *
     * 用法:
     * Java: .asParser(new ResponseParser<List<Student>>(){})
     * Kotlin: .asParser(object : ResponseParser<List<Student>>() {})
     *
     * 注：此构造方法一定要用protected关键字修饰，否则调用此构造方法将拿不到泛型类型
     */
    protected constructor() : super()

    /**
     * 此构造方法仅适用于不带泛型的Class对象，如: Student.class
     *
     * 用法
     * Java: .asParser(new ResponseParser<>(Student.class))   或者  .asResponse(Student.class)
     * Kotlin: .asParser(ResponseParser(Student::class.java)) 或者  .asResponse<Student>()
     */
    constructor(type: Type) : super(type)

    @Throws(IOException::class)
    override fun onParse(response: okhttp3.Response): T {
        val type: Type = ParameterizedTypeImpl[BaseResponseBean::class.java, mType] //获取泛型类型
        val data: BaseResponseBean<T> = response.convert(type)
        if (data.body == null) {
            throw ParseException(
                data.result.code,
                getErrorMessage("暂无数据"),
                response
            )
        }
        var t = data.body.records //获取data字段
        if (t == null && mType === String::class.java) {
            /*
             * 考虑到有些时候服务端会返回：{"errorCode":0,"errorMsg":"关注成功"}  类似没有data的数据
             * 此时code正确，但是data字段为空，直接返回data的话，会报空指针错误，
             * 所以，判断泛型为String类型时，重新赋值，并确保赋值不为null
             */
            @Suppress("UNCHECKED_CAST")
            t = data.result.message as T
        }
        if (data.result.code != "200") {
            throw ParseException(
                data.result.code,
                getErrorMessage(data.result.message),
                response
            )
        }
        return t!!
    }

    private fun getErrorMessage(errorCode: String): String {
        return when (errorCode) {
            "SYS_ERROR" -> "系统异常"
            "UN_KNOW_TRANS_ACTION_TYPE" -> "未知的动作类型"
            "HAS_NO_AUTHORITY" -> "未授权"
            "SAVE_ENTITY_ERROR" -> "操作实例异常"
            "CLIENT_OPERATION_ERROR" -> "客户端操作异常"
            "OBJECT_ID_IS_NULL" -> "对象ID不存在"
            "USER_NOT_EXIST" -> "用户不存在"
            "STATE_NOT_ALLOWED" -> "实例状态不允许"
            "OBJECT_NOT_EXIST" -> "对象不存在"
            "OPP_MULTIPLE_RECORDS" -> "商机已存在"
            "FIELD_CANNOT_EMPTY" -> "属性不能为空"
            "TOKEN_INVALID" -> "Token验证失败"
            else -> errorCode
        }
    }
}